package com.gpj.learn.concurrent.jol.demo;

import com.gpj.learn.concurrent.jol.Example;
import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;

/**
 * @className JolDemo3
 * @description
 *   查看启用偏向锁之后，加锁时对象头的变化
 *   TODO
 *      JVM关于偏向锁的参数
 *        - 启用参数: -XX:+UseBiasedLocking
 *        - 禁用参数: -XX:-UseBiasedLocking
 *        - 关闭延迟: -XX:BiasedLockingStartupDelay=0
 *   TODO
 *      - 启用偏向锁的时候(并且超过偏向锁启用延迟之后)，创建的对象的对象头(mark word)中锁的类型都为偏向锁--101
 *      - 不论创建的对象是都被设置为锁对象(即被synchronized关键字使用)，对象的锁类型都为偏向锁(而非无锁状态)
 *      - 当对象调用了hashcode方法，由于对象的对象头要存储对象的hashcode，则该对象不能再被设置为偏向锁
 *      - 刚被创建的对象虽然对象头中锁类型为偏向锁，但是对应的偏向类型为空(即00000000...00000000),该状态称之为偏向状态
 * @author GPJ
 * @date 2020/6/15 8:38
 * @version 1.0
 **/
@Slf4j
public class JolDemo3 {
    public static void main(String[] args) {
        // -XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0 通过前面的参数启用偏向数，并且设置偏向锁的延迟为0
        Example example = new Example();

        log.info("JVM 信息如下");
        log.info("{}", VM.current().details());
        log.info("----{}----","before");
        log.info(ClassLayout.parseInstance(example).toPrintable());
        synchronized (example){
            log.info("----{}----","locking");
            log.info(ClassLayout.parseInstance(example).toPrintable());
        }
        log.info("----{}----","after");
        log.info(ClassLayout.parseInstance(example).toPrintable());
    }
}
